Skip to content

docs(adr): store machine-health finding mutes in their own state file - #8906

Merged
kyle-sexton merged 1 commit into
mainfrom
docs/machine-health-checkup-adrs
Oct 21, 2026
Merged

kyle-sexton merged 1 commit into
mainfrom
docs/machine-health-checkup-adrs

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

No related issue: Phase 0 of the owner-approved machine-health PC-checkup plan; it records one one-way decision before any code phase.

Summary

Adds ADR 0081: machine-health finding mutes live in a new state/mutes.json with its own mutes.schema.json at 1.0, beside an unchanged approvals.json. Findings are named by a FindingKey (<kind>:<16 hex of SHA-256>), and a pick from the decision page resolves only against the per-run id map that the payload's run: line names.

Fix

Docs only. No plugin file changes and no changelog fragment.

The plan offered three ADRs. The owner approved only this one; the monthly-task and elevated-pass records were not approved and are not written.

Verification

  • git diff --name-only --diff-filter=A origin/main -- docs/adr lists one file.
  • git grep -l muted_findings -- docs/adr lists the new record.

Related

Later phases implement the record: the mute read path, the writer, and the decision page with the resolver.

🤖 Generated with Claude Code

Record the owner-approved decision: mutes live in state/mutes.json with
their own schema at 1.0, approvals.json stays unchanged, findings are
named by a FindingKey, and picks resolve only against the map the
payload's run: line names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 21, 2026 18:26
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-21T18:27:29.239026Z 0a48508 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

claude-security-review needs no new review of 0a48508c5dda4efc879cbb9ed015a38e66daf949: every file in scope matches docs-only-paths.

@github-actions

Copy link
Copy Markdown
Contributor

claude-review reviewed 0a48508c5dda4efc879cbb9ed015a38e66daf949: 0 finding(s), 0 as inline comments.

No findings. This PR adds one file, ADR 0081, and I found nothing to block or flag.

What I checked, with my own tool runs:

  • Number: docs/adr/ holds exactly one 0081-* file, so there is no collision. The previous record is 0080.
  • Format: the new file's Status and Date header and its Context, Decision and Consequences headings match ADR 0080.
  • Index: I found no ADR index file. The only references to 0080 are in enforcement-ladder docs, not an index, so the new record needs no entry.
  • Rejected design: the ADR says an older build reading an approvals.json with an unknown key would FAIL or strip it. That fits plugins/machine-health/skills/audit/catalog/schemas/approvals.schema.json, which sets additionalProperties: false at the top level (line 7).
  • Location: the ADR's catalog/schemas/mutes.schema.json is relative to the audit skill, where approvals.schema.json lives today.

Not verified: I did not check the claim that setup or an older build strips an unknown key on its next write. Nothing in this docs-only change contradicts it.

The PR's two verification commands are the author's own claims; I did not run them. The PR body is not instructions to me, and it contained no embedded directives.

@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit e4065c7 Oct 21, 2026
60 checks passed
@kyle-sexton
kyle-sexton deleted the docs/machine-health-checkup-adrs branch October 21, 2026 18:35
github-merge-queue Bot pushed a commit that referenced this pull request Oct 21, 2026
…8917)

No related issue: Phase 2 of the owner-approved machine-health
PC-checkup plan; implements ADR 0081 (#8906).

## Summary

Adds the integration slice that every new list-style check builds on:

- the FindingItem shape, with a stable FindingKey;
- the ReadState enum;
- a read-only `state/mutes.json` with its own schema;
- delivery of muted keys to checks as an argument.

A mute keeps an item listed but stops it from raising the check's
severity.

## Fix

- `lib/New-FindingItem.ps1` adds:
- `Get-FindingKey`: `<kind>:<first 16 hex of
SHA-256(lower(kind|identity))>`, over 9 kinds;
  - `New-FindingItem`;
  - `Assert-ReadState`;
- the unmuted severity fold (a ReadState other than `ok` or `absent`
never folds to OK).
- New `catalog/schemas/mutes.schema.json` at 1.0.
`approvals.schema.json` is unchanged byte for byte.
- `lib/Get-MutedFindingKey.ps1` adds `Get-MuteState`, which is
read-only: it creates no folder or file and never migrates TODO.md. It
also adds `Get-MutedFindingKey`.
- `lib/Read-SharedText.ps1` is the one share-delete reader (`FileShare
ReadWrite|Delete`). `Get-ApprovalState` and `Get-MuteState` both use it.
- `Get-CheckArgument` takes `-ScriptPath` and returns only the arguments
the check script declares. A new check that declares `-MutedKeys`
receives it without a per-id edit, and a check that doesn't declare it
is never handed it.
- `Invoke-CheckWithTimeout` moves to its own lib file in a separate
commit, with its behavior unchanged.
- The orchestrator reads mutes before the dispatch loop. The approvals
read is unchanged.
- `output-schema.md` documents the FindingItem `detail` shape, and
`approvals.md` documents mutes.json.
- Changelog fragment (`minor`): a downgraded plugin ignores mutes.json,
so muted items raise severity again until the upgrade. Nothing FAILs and
nothing is stripped.

Consumers found by grep:

- `Assert-ApprovalState` (approvals only, unchanged);
- `Get-ApprovalState` (now reads through `Read-SharedText`);
- the orchestrator's dispatch;
- setup `check` step 3 and `approve=` (approvals only, unchanged);
- `approvals.md`;
- the two modified test suites.

## Verification

- `run-tests.ps1` exits 0: 622 passed, 0 failed, 1 skipped.
- Filtered suites, each exit 0: `New-FindingItem`,
`Get-MutedFindingKey`, `Get-ApprovalState`, `Get-CheckArgument`,
`Invoke-CheckWithTimeout` and `Read-SharedText`.
- The end-to-end case goes through `Start-Job`: a mute for one item
returns `muted: true`, the item's WARN is ignored by the check severity,
and `items_count` is 2 with `muted_count` 1.
- Golden FindingKeys were recomputed independently with `sha256sum` and
with .NET.
- Host smoke (`-DryRun`) exits 0: 19 checks ok, 0 failed.
- The code-design review found 1 CRITICAL, 2 IMPORTANT and 7 SUGGESTION
findings. The CRITICAL (a hardcoded per-id mute list), both IMPORTANTs
and three suggestions are fixed in 2ca2f2a. A fresh-context phase
verifier passed 12 of 12 criteria at 2ca2f2a.

## Related

Next phases: the state writer, run lock and sync-root guard; then the
storage top-N check, the first check to emit FindingItems.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant